package com.chzsyh.evwer.ui.web

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.res.Configuration
import android.graphics.Bitmap
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.Message
import android.util.DisplayMetrics
import android.util.Log
import android.view.View
import android.webkit.*
import com.alibaba.android.arouter.facade.annotation.Route
import com.chzsyh.evwer.BuildConfig
import com.chzsyh.evwer.R
import com.chzsyh.evwer.databinding.FragmentWebViewBinding
import com.chzsyh.evwer.vm.WebViewFragmentVM
import com.google.gson.Gson
import com.gyf.immersionbar.ImmersionBar
import com.owbtgad.common.base.BaseLiveData
import com.owbtgad.common.base.BaseMFragment
import com.owbtgad.common.interfaces.WebUrl
import com.owbtgad.common.utils.*
import org.json.JSONException
import org.json.JSONObject
import java.io.Serializable
import java.util.*

@Route(path = ARouterString.Fragment.WEB_FRAGMENT)
class WebFragment : BaseMFragment<FragmentWebViewBinding, WebViewFragmentVM>(), WebUrl {
    private var mUploadMessage: ValueCallback<Uri?>? = null
    private var mUploadMessageForAndroid5: ValueCallback<Array<Uri>>? = null
    private var mWebView: WebView? = null
    private val mTitles: MutableMap<String?, String> = HashMap()
    private var mIntentUrl: String? = null
    private var mCurrentUrl: String? = null
    private var mTitleString: String? = null
    private val mWebBack = WebViewBack()
    private var isNotReload // true不刷新
            = false
    private val callBackLiveData = BaseLiveData<String>()
    private var mOpenNotice: String? = null
    private val mToolbarIcon = BaseLiveData<Int>()
    private val mTestHandler: Handler? = object : Handler() {
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            when (msg.what) {
                MSG_INIT_UI -> init()
            }
        }
    }

    override fun getContentLayout(): Int {
        return R.layout.fragment_web_view
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.also {
            mTitleString = it.getString("title")
            mIntentUrl = it.getString("url")
            mCurrentUrl = mIntentUrl
        }
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        ImmersionBar.with(this)
            .titleBar(mBinding.toolbar)
            .transparentStatusBar()
            .statusBarDarkFont(true)
            .init()
        mBinding.viewModel = mViewModel
        MyUtils.viewClicks(mBinding.includeUnknownHost.clClick) { }
        mBinding.toolbar.setNavigationOnClickListener { mLeftClick() }
        mTestHandler?.sendEmptyMessageDelayed(MSG_INIT_UI, 10)
        mToolbarIcon.observe(viewLifecycleOwner, { integer: Int ->
            mWebBack.type = integer
            if (integer == 0) {
                mBinding.toolbar.setNavigationIcon(R.drawable.ic_baseline_arrow_back)
            } else if (integer == 1) {
                mBinding.toolbar.navigationIcon = null
            }
        })
    }

    private fun init() {
        mWebView = X5WebView(getFixedContext(mContext!!), null)
        mBinding.fl.addView(mWebView, mBinding.fl.layoutParams)
        if (Build.VERSION.SDK_INT >= 28) {
            mWebView?.setLayerType(View.LAYER_TYPE_HARDWARE, null)
        }
        callBackLiveData.observe(this) { s: String ->
            Log.d(Companion.TAG, "callBackLiveData: $s")
            mWebView?.evaluateJavascript(s) { }
        }
        val dm = DisplayMetrics()
        requireActivity().windowManager.defaultDisplay.getMetrics(dm)
        mBinding.progressBar.max = 80
        MyUtils.viewClicks(mBinding.includeUnknownHost.btnRefresh) { onReload() }
        mWebView?.webViewClient = object : WebViewClient() {
            override fun onPageStarted(webView: WebView, s: String, bitmap: Bitmap) {
                super.onPageStarted(webView, s, bitmap)
                mCurrentUrl = s
                if (s.contains("/h5/loanResultPay")) {
                    mToolbarIcon.update(1)
                } else {
                    mToolbarIcon.update(0)
                }
                mWebBack.type = 0
                mBinding.toolbar.setNavigationIcon(R.drawable.ic_baseline_arrow_back)
                mWebBack.homeState = null
                mOpenNotice = null
                mWebBack.url = null
                isNotReload = false
                Log.d(Companion.TAG, "onPageStarted: ")
            }

            override fun onReceivedError(webView: WebView, errorCode: Int, s: String, s1: String) {
                super.onReceivedError(webView, errorCode, s, s1)
                if (!mIntentUrl!!.contains(
                        BuildConfig.baseUrl.replace("http://", "").replace("https://", "")
                    )
                ) {
                    finish()
                    return
                }
                mBinding.includeUnknownHost.clClick.visibility = View.VISIBLE
                mBinding.includeUnknownHost.btnRefresh.tag = 1
            }

            override fun onPageFinished(view: WebView, url: String) {
                super.onPageFinished(view, url)
                val title = mTitles[mCurrentUrl]
                if (title != null && title.isNotEmpty()) {
                    mBinding.toolbar.title = title
                } else if (mTitleString != null && !mTitleString!!.isEmpty()) {
                    mBinding.toolbar.title = mTitleString
                }
                if (url.contains("/h5/loanResultPay")) {
                    mToolbarIcon.update(1)
                } else {
                    mToolbarIcon.update(0)
                }
                if (url.contains(
                        BuildConfig.baseUrl.replace("http://", "").replace("https://", "")
                    )
                ) {
                    val map = stringObjectMap
                    val json = Gson().toJson(map)
                    callBackLiveData.update("getConfigFromApp($json)")
                }
            }
        }
        mWebView?.webChromeClient = object : WebChromeClient() {
            override fun onReceivedTitle(webView: WebView, s: String) {
                super.onReceivedTitle(webView, s)
                if (mCurrentUrl != null) {
                    Log.d(Companion.TAG, "onReceivedTitle: $s")
                    if (s.isNotEmpty()) {
                        mTitles[mCurrentUrl] = s
                        val title = mTitles[mCurrentUrl]
                        mBinding.toolbar.title = title
                    }
                }
            }

            override fun onProgressChanged(webView: WebView, newProgress: Int) {
                super.onProgressChanged(webView, newProgress)
                if (newProgress > 80) {
                    if (mBinding.progressBar.visibility == View.VISIBLE) {
                        mBinding.progressBar.visibility = View.GONE
                    }
                } else {
                    mBinding.progressBar.progress = newProgress
                    if (mBinding.progressBar.visibility != View.VISIBLE) {
                        mBinding.progressBar.visibility = View.VISIBLE
                    }
                }
            }

            // For Android  > 4.1.1
            fun openFileChooser(
                uploadMsg: ValueCallback<Uri?>,
                acceptType: String?,
                capture: String?
            ) {
                openFileChooserImpl(uploadMsg)
            }

            // For Android  >= 5.0
            override fun onShowFileChooser(
                webView: WebView,
                filePathCallback: ValueCallback<Array<Uri>>,
                fileChooserParams: FileChooserParams
            ): Boolean {
                mUploadMessageForAndroid5 = filePathCallback
                openFileChooseImplForAndroid()
                return true
            }

            // For Android 3.0+
            fun openFileChooser(uploadMsg: ValueCallback<Uri?>, acceptType: String?) {
                openFileChooserImpl(uploadMsg)
            }

            // For Android < 3.0
            fun openFileChooser(uploadMsgs: ValueCallback<Uri?>) {
                openFileChooserImpl(uploadMsgs)
            }
        }
        setUrl(mIntentUrl)
        CookieSyncManager.createInstance(mContext)
        CookieSyncManager.getInstance().sync()
    }

    override fun onStart() {
        super.onStart()
        if (mOpenNotice != null) {
            if (MyUtils.isNotificationEnabled(mContext)) {
                callBackLiveData.update(mOpenNotice!!)
            }
        }
        mOpenNotice = null
    }

    private fun onReload() {
        mBinding.includeUnknownHost.clClick.visibility = View.GONE
        if (mWebView != null && !isNotReload) {
            mWebView!!.reload()
        }
    }

    private fun getBaseUrl(url: String?): String? {
        if (url != null && url.isNotEmpty()) {
            val i = url.indexOf("?")
            return if (i > 0) {
                url.substring(0, i)
            } else {
                url
            }
        }
        return url
    }

    fun mLeftClick() { //返回处理
        if (mWebView != null) {
            when (mWebBack.type) {
                0 -> {
                    val url1 = getBaseUrl(mIntentUrl)
                    val url2 = getBaseUrl(mCurrentUrl)
                    if (url1 != url2 && mWebView!!.canGoBack()) {
                        mWebView!!.goBack()
                    } else {
                        finish()
                    }
                }
                1 -> {
                }
                else -> {
                }
            }
        }
    }

    /**
     * 处理部分机型异常
     *
     * @param context
     * @return
     */
    private fun getFixedContext(context: Context): Context {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            context.createConfigurationContext(Configuration())
        } else {
            context
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        val result = if (data == null || resultCode != Activity.RESULT_OK) null else data.data
        if (resultCode == Activity.RESULT_OK) {
            when (requestCode) {
                FILE_CHOOSER_RESULT_CODE_FOR_ANDROID_5 -> {
                    if (null == mUploadMessageForAndroid5) return
                    if (result != null) {
                        mUploadMessageForAndroid5!!.onReceiveValue(arrayOf(result))
                    } else {
                        mUploadMessageForAndroid5!!.onReceiveValue(arrayOf())
                    }
                    mUploadMessageForAndroid5 = null
                }
                FILE_CHOOSER_RESULT_CODE -> {
                    if (null == mUploadMessage) return
                    mUploadMessage!!.onReceiveValue(result)
                    mUploadMessage = null
                }
                else -> {
                }
            }
        }
    }

    override fun onDestroyView() {
        mTestHandler?.removeCallbacksAndMessages(null)
        if (mWebView != null) mWebView!!.destroy()
        super.onDestroyView()
    }

    override fun setUrl(url: String?) {
        var url: String? = url
        if (url != null && url.isNotEmpty()) {
            mWebView!!.addJavascriptInterface(MyJavaScriptInterface(), "android")
            if (url.contains(BuildConfig.baseUrl.replace("http://", "").replace("https://", ""))) {
                url = if (url.contains("?")) {
                    url + "&time=" + System.currentTimeMillis()
                } else {
                    url + "?time=" + System.currentTimeMillis()
                }
            }
            mWebView!!.loadUrl(url)
        }
    }

    /**
     * android 5.0 以下开启图片选择（原生）
     *
     *
     * 可以自己改图片选择框架。
     */
    private fun openFileChooserImpl(uploadMsg: ValueCallback<Uri?>) {
        mUploadMessage = uploadMsg
        val i = Intent(Intent.ACTION_GET_CONTENT)
        i.addCategory(Intent.CATEGORY_OPENABLE)
        i.type = "image/*"
        startActivityForResult(Intent.createChooser(i, "File Chooser"), FILE_CHOOSER_RESULT_CODE)
    }

    /**
     * android 5.0(含) 以上开启图片选择（原生）
     *
     *
     * 可以自己改图片选择框架。
     */
    protected fun openFileChooseImplForAndroid() {
        val contentSelectionIntent = Intent(Intent.ACTION_GET_CONTENT)
        contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE)
        contentSelectionIntent.type = "image/*"
        val chooserIntent = Intent(Intent.ACTION_CHOOSER)
        chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent)
        chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser")
        startActivityForResult(chooserIntent, FILE_CHOOSER_RESULT_CODE_FOR_ANDROID_5)
    }

    private val stringObjectMap: Map<String, Any>
        private get() = InsertHelp.getHeadMap(mContext)

    private inner class MyJavaScriptInterface {
        @JavascriptInterface
        fun openNative(jsondata: String) {
            Log.i(Companion.TAG, "openNative: $jsondata")
            val bean = Gson().fromJson(jsondata, OpenBean::class.java)
            var param: JSONObject? = null
            when (bean.jump) {
                "IT_goHome" -> if (bean.param != null && bean.param!!.isNotEmpty()) {
                    try {
                        param = JSONObject(bean.param)
                        val status = param.optInt("status")
                        val bundle = Bundle()
                        bundle.putInt("status", status)
                        ActivityUtils.startMain(1, bundle)
                    } catch (e: JSONException) {
                        e.printStackTrace()
                    }
                }
                "IT_loginOut" -> {
                    if (bean.param != null && bean.param!!.isNotEmpty()) {
                        try {
                            param = JSONObject(bean.param)
                            val toast = param.optString("toast")
                            ToastUtils.showToast(mContext, toast)
                        } catch (e: JSONException) {
                            e.printStackTrace()
                        }
                    }
                    ActivityUtils.startMain()
                }
                "IT_authentication" -> ActivityUtils.showActivity(ARouterString.Auth.CERTIFICATION_ACTIVITY)
                "IT_hiddenBack" -> mToolbarIcon.update(1)
                else -> throw IllegalStateException("Unexpected value: " + bean.jump)
            }
        }
    }

    private inner class OpenBean : Serializable {
        var jump: String? = null
        var param: String? = null
        var callBack: String? = null
    }

    private inner class WebViewBack : Serializable {
        var type = 0 //返回处理类型 0默认处理 1隐藏返回 2返回到指定界面
        var homeState //如果该数据存在则跳转首页
                : String? = null
        var refreshState //如果true跳转首页刷新
                = false
        var url //如果homeState数据不存在，则跳转回到指定页
                : String? = null
    }

    companion object {
        private const val MSG_INIT_UI = 1
        private const val FILE_CHOOSER_RESULT_CODE = 34 //选择图片
        private const val FILE_CHOOSER_RESULT_CODE_FOR_ANDROID_5 = 33 //选择图片
        private const val TAG = "WebFragment"

        @JvmStatic
        fun newInstance(url: String, title: String?): WebFragment {
            val args = Bundle()
            args.putString("title", title)
            args.putString("url", url)
            val fragment = WebFragment()
            fragment.arguments = args
            return fragment
        }
    }

}